package com.j2eefast.flowable.bpm.service;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.j2eefast.common.core.mutidatasource.annotaion.DataSource;
import com.j2eefast.common.core.page.Query;
import com.j2eefast.common.core.utils.PageUtil;
import com.j2eefast.common.core.utils.ResponseData;
import com.j2eefast.common.core.utils.ToolUtil;
import com.j2eefast.flowable.bpm.entity.*;
import com.j2eefast.flowable.bpm.mapper.BpmBidOpeningMapper;
import com.j2eefast.flowable.bpm.mapper.BpmOaFormMapper;
import com.j2eefast.flowable.bpm.mapper.BpmTaskMapper;
import com.j2eefast.flowable.bpm.mapper.ProcessInstanceMapper;
import com.j2eefast.framework.utils.UserUtils;
import org.checkerframework.checker.units.qual.A;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.ui.task.service.runtime.FlowableTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 开标信息登记表Service接口
 * @author: ZhouZhou
 * @date 2020-04-20 22:19
 */
@Service
public class BpmBidOpeningFormService extends ServiceImpl<BpmBidOpeningMapper, BpmBidOpeningEntity> {

	@Resource
	@Lazy
	private BpmBidOpeningFormService bpmBidOpeningFormService;
	@Autowired
	private FlowableProcessInstanceService flowableProcessInstanceService;
	@Autowired
	private BpmFormDraftService bpmFormDraftService;

	/**
	 * 页面分页查询
	 */
	public PageUtil findPage(Map<String, Object> params) {
		QueryWrapper<BpmBidOpeningEntity> r = new QueryWrapper<BpmBidOpeningEntity>();
		Page<BpmBidOpeningEntity> page = this.baseMapper.selectPage(new Query<BpmBidOpeningEntity>(params).getPage(), r);
		return new PageUtil(page);
	}

	/**
	 * 保存表单并发起审批
	 */
	@Transactional(rollbackFor = Exception.class)
	public ResponseData addForm(BpmBidOpeningEntity bpmBidOpeningEntity){

		//请填写 这三个字段 ProcessDefinitionKey,BusinessKey,SystemSn
		bpmBidOpeningEntity.setId(IdUtil.fastSimpleUUID());
		bpmBidOpeningEntity.setUserId(String.valueOf(UserUtils.getUserId()));
		bpmBidOpeningEntity.setTitle(this.formatTitle(bpmBidOpeningEntity.getTitle(), bpmBidOpeningEntity));

		ResponseData returnStart = this.startProcess(bpmBidOpeningEntity);
		if(!returnStart.get("code").equals("00000")) {
			return returnStart;
		}

		String processInstanceId = ((ProcessInstance)returnStart.get("data")).getProcessInstanceId();
		bpmBidOpeningEntity.setProcessInstanceId(processInstanceId);
		BpmFormDraftEntity bpmFormDraftEntity = this.prepareFormDraft(bpmBidOpeningEntity,false);
		bpmFormDraftService.save(bpmFormDraftEntity);
		return bpmBidOpeningFormService.save(bpmBidOpeningEntity)? ResponseData.success(): ResponseData.error("数据插入失败!");
	}

	/**
	 * 将表单进行保存，不发起流程
	 * @param bpmBidOpeningEntity
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public ResponseData saveAsDraft(BpmBidOpeningEntity bpmBidOpeningEntity){
		//请填写 这三个字段 ProcessDefinitionKey,BusinessKey,SystemSn
		bpmBidOpeningEntity.setId(IdUtil.fastSimpleUUID());
		bpmBidOpeningEntity.setUserId(String.valueOf(UserUtils.getUserId()));
		bpmBidOpeningEntity.setTitle(this.formatTitle(bpmBidOpeningEntity.getTitle(), bpmBidOpeningEntity));
		bpmBidOpeningEntity.setStatus("0");

		//写入草稿数据
		BpmFormDraftEntity bpmFormDraftEntity = this.prepareFormDraft(bpmBidOpeningEntity,true);
		bpmFormDraftService.save(bpmFormDraftEntity);
		return bpmBidOpeningFormService.save(bpmBidOpeningEntity)? ResponseData.success(): ResponseData.error("数据插入失败!");
	}

	/**
	 * 将待发表单重新发起流程
	 * @param formDraftId
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public ResponseData sendForm(String formDraftId){


		//更新FormDraft的状态
		BpmFormDraftEntity bpmFormDraftEntity = bpmFormDraftService.getById(formDraftId);
		BpmFormDraftEntity toUpdateDraft = new BpmFormDraftEntity();
		toUpdateDraft.setStatus("2");
		toUpdateDraft.setId(bpmFormDraftEntity.getId());
		bpmFormDraftService.updateDataById(toUpdateDraft);


		BpmBidOpeningEntity bpmBidOpeningEntity = bpmBidOpeningFormService.getFormById(bpmFormDraftEntity.getFormDataId());

		//请填写 这三个字段 ProcessDefinitionKey,BusinessKey,SystemSn
		ResponseData returnStart = this.startProcess(bpmBidOpeningEntity);
		if(!returnStart.get("code").equals("00000")){
			return returnStart;
		}

		BpmBidOpeningEntity toUpdate = new BpmBidOpeningEntity();
		toUpdate.setId(bpmBidOpeningEntity.getId());
		toUpdate.setProcessInstanceId(((ProcessInstance)returnStart.get("data")).getProcessInstanceId());
		return bpmBidOpeningFormService.updateById(toUpdate)? ResponseData.success(): ResponseData.error("发起流程失败!");
	}

	/**
	 * 修改未发起审批的表单
	 * @param bidOpeningForm
	 * @return
	 */
	public boolean editForm(BpmBidOpeningEntity bidOpeningForm){
		BpmFormDraftEntity bpmFormDraftEntity = bpmBidOpeningFormService.prepareFormDraft(bidOpeningForm, true);
		bpmFormDraftService.updateByFormDataId(bpmFormDraftEntity);
		return this.updateById(bidOpeningForm);
	}

	/**
	 * 根居ID获取对象
	 */
	public BpmBidOpeningEntity getFormById(String id){
		return this.getById(id);
	}

	/**
	 * 启动流程实例
	 * @param bpmBidOpeningEntity
	 * @return
	 */
	private ResponseData startProcess(BpmBidOpeningEntity bpmBidOpeningEntity){
		//请填写 这三个字段 ProcessDefinitionKey,BusinessKey,SystemSn
		StartProcessInstanceEntity startProcessInstanceVo = new StartProcessInstanceEntity();
		startProcessInstanceVo.setBusinessKey(bpmBidOpeningEntity.getId());
		startProcessInstanceVo.setCreator(String.valueOf(UserUtils.getUserId()));
		startProcessInstanceVo.setCurrentUserCode(String.valueOf(UserUtils.getUserId()));
		startProcessInstanceVo.setFormName(bpmBidOpeningEntity.getTitle());
		startProcessInstanceVo.setSystemSn("system");
		//startProcessInstanceVo.setProcessDefinitionKey(bpmBidOpeningEntity.getModelKey());
		startProcessInstanceVo.setProcessDefinitionKey(bpmBidOpeningEntity.getModelKey());
		System.out.println(startProcessInstanceVo.getSystemSn());
		System.out.println("--------------------------------");

		Map<String, Object> variables = new HashMap<>();
		variables.put("priority", bpmBidOpeningEntity.getPriority());
		startProcessInstanceVo.setVariables(variables);

		return flowableProcessInstanceService.startProcessInstanceByKey(startProcessInstanceVo);

	}

	public BpmFormDraftEntity prepareFormDraft(BpmBidOpeningEntity bpmBidOpeningEntity, boolean active){
		//写入草稿
		BpmFormDraftEntity bpmFormDraftEntity = new BpmFormDraftEntity();
		bpmFormDraftEntity.setTitle(bpmBidOpeningEntity.getTitle());
		bpmFormDraftEntity.setUserId(String.valueOf(UserUtils.getUserId()));
        //这是一个固定的数据，每个表单表有一个url prefix
		bpmFormDraftEntity.setUrl("bpm/bidopening");
        bpmFormDraftEntity.setStatus("1");
        bpmFormDraftEntity.setPriority(bpmBidOpeningEntity.getPriority());
		bpmFormDraftEntity.setFormDataId(bpmBidOpeningEntity.getId());
		bpmFormDraftEntity.setCreateTime(new Date());
		if(bpmBidOpeningEntity.getProcessInstanceId()!=null){
			bpmFormDraftEntity.setProcessInstanceId(bpmBidOpeningEntity.getProcessInstanceId());
		}
		String activeFlag = active?"1":"0";
		bpmFormDraftEntity.setActive(activeFlag);
		return bpmFormDraftEntity;
	}

	protected String formatTitle(String title, BpmBidOpeningEntity bpmBidOpeningEntity){
		//{项目名称}项目报备申请-{创建人}（{创建时间}）
		title = title.replace("{项目名称}", bpmBidOpeningEntity.getProjectName());
		title = title.replace("{创建人}", bpmBidOpeningEntity.getProjectAdmin());
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(bpmBidOpeningEntity.getCreateTime());
		return title.replace("{创建时间}", dateString);
	}

}